//
// Created by shen on 8/10/2024.
//

#include "AudioDecoder.h"

void AudioDecoder::OnDecoderReady() {

    if (m_AudioRender){
        AVCodecContext *codeCtx=GetCodecContext();
        m_SwrContext=swr_alloc();

        av_opt_set_int(m_SwrContext, "in_channel_layout", codeCtx->channel_layout, 0);
        av_opt_set_int(m_SwrContext, "out_channel_layout", AUDIO_DST_CHANNEL_LAYOUT, 0);
        av_opt_set_int(m_SwrContext, "in_sample_rate", codeCtx->sample_rate, 0);
        av_opt_set_int(m_SwrContext, "out_sample_rate", AUDIO_DST_SAMPLE_RATE, 0);
        av_opt_set_sample_fmt(m_SwrContext, "in_sample_fmt", codeCtx->sample_fmt, 0);
        av_opt_set_sample_fmt(m_SwrContext, "out_sample_fmt", DST_SAMPLT_FORMAT,  0);

        swr_init(m_SwrContext);

        //sample rate: 44100, channel: 2, format: signed 16 bits, frame_size: 1024, layout: AV_CH_LAYOUT_STEREO //双通道
        //sample rate: 44100, channel: 2, format: 8, frame_size: 1024, layout: 3
        LOGCATE("AudioDecoder::OnDecoderReady audio metadata sample rate: %d, channel: %d, format: %d, frame_size: %d, layout: %lld",
                codeCtx->sample_rate, codeCtx->channels, codeCtx->sample_fmt, codeCtx->frame_size,codeCtx->channel_layout);
        //时间基转换函数   因为输出的每一秒要一样 //1024  一帧的采样个数         //44100 一秒钟采样44100       //采样率 当前的采样率   目标的采样个数
        // 1024 * 44100/sample_rate    //目标采样率
        m_nbSamples= av_rescale_rnd(ACC_NB_SAMPLES, AUDIO_DST_SAMPLE_RATE, codeCtx->sample_rate, AV_ROUND_UP);
        //获取给定音频参数所需的缓冲区大小。   获取缓冲区的大小      通道数  采样个数 采样格式  1字节对齐  一秒钟的数据大小
        m_DstFrameDataSze = av_samples_get_buffer_size(NULL, AUDIO_DST_CHANNEL_COUNTS,m_nbSamples, DST_SAMPLT_FORMAT, 1);

        LOGCATE("AudioDecoder::OnDecoderReady [m_nbSamples, m_DstFrameDataSze]=[%d, %d]", m_nbSamples, m_DstFrameDataSze);

        m_AudioOutBuffer = (uint8_t *) malloc(m_DstFrameDataSze);

        m_AudioRender->Init();
    }

}


void AudioDecoder::OnDecoderDone() {
    LOGCATE("AudioDecoder::OnDecoderDone");
    if(m_AudioRender)
        m_AudioRender->UnInit();

    if(m_AudioOutBuffer) {
        free(m_AudioOutBuffer);
        m_AudioOutBuffer = nullptr;
    }

    if(m_SwrContext) {
        swr_free(&m_SwrContext);
        m_SwrContext = nullptr;
    }

}

void AudioDecoder::ClearCache() {

    if(m_AudioRender)
        m_AudioRender->ClearAudioCache();
}

void AudioDecoder::OnFrameAvailable(AVFrame *frame) {
    LOGCATE("result1   RenderAudeeeiddd222oFrame");
    if (m_AudioRender){
        LOGCATE("result1   RenderAudeeeidddoFrame");
        int result= swr_convert(m_SwrContext,
                                &m_AudioOutBuffer,
                                m_DstFrameDataSze/2,
                                (const uint8_t **)frame->data,
                                frame->nb_samples);
        if (result > 0 ) {
            //RenderAudidddoFrame 1024  1024  4096
            LOGCATE("result1   RenderAudidddoFrame %d  %d  %d",result,frame->nb_samples,m_DstFrameDataSze);
            m_AudioRender->RenderAudioFrame(m_AudioOutBuffer, m_DstFrameDataSze);
        }
    }
}